package cn.itrip.trade.controller;

import cn.itrip.commons.DtoUtils;
import cn.itrip.dto.Dto;
import cn.itrip.entity.ItripHotelOrder;
import cn.itrip.trade.sdk.alipay.AlipayConfig;
import cn.itrip.trade.sdk.wx.MyVXPayConfig;
import cn.itrip.trade.sdk.wx.WXPay;
import cn.itrip.trade.sdk.wx.WXPayUtil;
import cn.itrip.trade.service.OrderService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Super God Jie
 * @version 1.0  2022-04-17 22:42
 */
@Controller
@RequestMapping("/api")
public class PrepayController {
	@Resource
	private OrderService orderService;

	@GetMapping("/prepay/{orderNo}")
	public void aliPay(@PathVariable String orderNo,
					   HttpServletRequest req, HttpServletResponse response) throws IOException, AlipayApiException {
		req.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");

		//获得初始化的AlipayClient
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,
				AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY,
				AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
				AlipayConfig.SIGNTYPE);

		//设置请求参数
		AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
		//同步回调回调不过来，只写异步即可
		//alipayRequest.setReturnUrl(AlipayConfig.return_url);
		alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

		ItripHotelOrder order = orderService.aliQueryOrderInfo(orderNo);
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", order.getOrderNo());
		bizContent.put("total_amount", order.getPayAmount());
		bizContent.put("subject", order.getHotelName());
		bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

		alipayRequest.setBizContent(bizContent.toString());
		AlipayTradePagePayResponse aliResponse = alipayClient.pageExecute(alipayRequest);
		if (aliResponse.isSuccess()) {
			System.out.println("调用成功");
		} else {
			System.out.println("调用失败");
		}
		String body = aliResponse.getBody();
		response.getWriter().print(body);
	}

	//同步回调  只做输出
	@RequestMapping("/callBack")
	public void noAsynCallBack(HttpServletRequest request) {
		Map<String, String[]> parameterMap = request.getParameterMap();
		System.err.println(JSON.toJSONString(parameterMap));
		System.out.println("同步回调输出相关信息==========>>>>>>==========>>>>>>");
		System.out.println("orderService.aliQueryOrderInfo(parameterMap.get(\"out_trade_no\")[0]) = " +
				orderService.aliQueryOrderInfo(parameterMap.get("out_trade_no")[0]));
	}

	//异步回调处理业务
	@RequestMapping("/asynCallBack")
	@ResponseBody
	public Dto asynCallBack(HttpServletRequest request) {
		Map<String, String[]> parameterMap = request.getParameterMap();
		System.out.println("异步回调修改库存信息==========>>>>>>==========>>>>>>");
		//订单号
		String orderNo = parameterMap.get("out_trade_no")[0];
		String tradeNo = parameterMap.get("trade_no")[0];
		//将订单修改为支付成功为2, 支付方式为payType为1  修改实时库存表
		try {
			orderService.updateOrderStatusANDPayType_modifyStore(orderNo, tradeNo);
			return DtoUtils.returnSuccess(null);
		} catch (Exception e) {
			return DtoUtils.returnFail("50005", e.getMessage());
		}
	}

	/**
	 * 微信支付
	 */
	@GetMapping("/wxpay/createqccode/{orderNo}")
	@ResponseBody
	public Dto vxPay(@PathVariable String orderNo) throws Exception {
		// 发起微信支付
		WXPay wxpay = null;
		ItripHotelOrder order = orderService.aliQueryOrderInfo(orderNo);

		wxpay = new WXPay(new MyVXPayConfig());

		Map<String, String> data = new HashMap<String, String>();
		data.put("body", order.getHotelName());
		data.put("out_trade_no", order.getOrderNo()); // 订单唯一编号, 不允许重复
		data.put("total_fee", "1"); // 订单金额, 单位分
		data.put("spbill_create_ip", "127.0.0.1"); // 下单ip
		// 订单结果通知, 微信主动回调此接口
		data.put("notify_url", "http://ni2i63.natappfree.cc/trade/api/vxPayRollBack");
		data.put("trade_type", "NATIVE"); // 固定填写

		Map<String, String> responseData = wxpay.unifiedOrder(data);
		System.out.println("\"下单支付信息：\"+JSONObject.toJSONString(responseData) 下单支付信息："
				+ JSONObject.toJSONString(responseData));

		String returnCode = responseData.get("return_code");
		if ("SUCCESS".equals(returnCode)) {
			Map<String, Object> da = new HashMap<>();
			System.out.println("链接：responseData.get(\"code_url\") = " + responseData.get("code_url"));
			da.put("codeUrl", responseData.get("code_url"));
			da.put("payAmount", order.getPayAmount());
			da.put("count", order.getCount());
			da.put("hotelName", order.getHotelName());
			da.put("roomId", order.getRoomId());
			return DtoUtils.returnSuccess(da);
		} else {
			return DtoUtils.returnFail("50001", responseData.get("return_msg"));
		}
	}

	private final String SUCCESS = "SUCCESS";
	//异步回调处理业务
	@RequestMapping("/vxPayRollBack")
	public void vxPayRollBack(HttpServletRequest request,HttpServletResponse response) throws Exception {
		//将订单修改为支付成功为2, 支付方式为payType为1  修改实时库存表
		String s = IOUtils.toString(request.getInputStream());
		Map<String, String> toMap = WXPayUtil.xmlToMap(s);

		String orderNo = toMap.get("out_trade_no");
		String tradeNo = toMap.get("transaction_id");
		orderService.updateOrderStatusANDPayType_modifyStore(orderNo, tradeNo);

		Map<String,String> result = new HashMap<>();
		if(toMap.get("return_code").equals(SUCCESS)){
			result.put("return_code",SUCCESS);
			result.put("return_msg","OK");
		} else {
			result.put("return_code","FAIL");
			result.put("return_msg","支付失败");
		}
		PrintWriter writer = response.getWriter();
		writer.print(WXPayUtil.mapToXml(result));
	}

	@GetMapping("/wxpay/queryorderstatus/{orderNo}")
	@ResponseBody
	public Dto queryorderstatus(@PathVariable String orderNo) {
		return DtoUtils.returnSuccess(orderService.queryOrderNo(orderNo));
	}
}
